﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Forms;

namespace UIShare
{

    public delegate void Action<T>(T obj);
    public delegate void Action<T1, T2>(T1 arg1, T2 arg2);
    public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
    public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
    public delegate void Action<T1, T2, T3, T4, T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
    public delegate void Action<T1, T2, T3, T4, T5, T6>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
    public delegate void Action<T1, T2, T3, T4, T5, T6, T7>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);


    /// <summary>
    /// 类<code>ControlThreadCaller</code>:提供线程安全的UI调用方式, invokeTarget一般为 Control
    /// </summary>
    public class ControlThreadCaller : MarshalByRefObject
    {

        private static readonly object[] emptyObjectArray = new object[0];

        private readonly ISynchronizeInvoke invokeTarget;

        public ControlThreadCaller(ISynchronizeInvoke invokeTarget)
        {
            Debug.Assert(invokeTarget != null);
            this.invokeTarget = invokeTarget;
        }

        public override object InitializeLifetimeService()
        {
            return null;
        }

        public void Invoke(MethodInvoker method)
        {
            if (InvokeRequired)
            {
                invokeTarget.BeginInvoke(method, emptyObjectArray);
            }
            else
            {
                method();
            }
        }

        public void Invoke<T>(Action<T> method, T argument)
        {
            if (InvokeRequired)
            {
                invokeTarget.BeginInvoke(method, new object[] { argument });
            }
            else
            {
                method(argument);
            }
        }

        public void Invoke<T1, T2>(Action<T1, T2> method, T1 argument1, T2 argument2)
        {
            if (InvokeRequired)
            {
                invokeTarget.BeginInvoke(method, new object[] { argument1, argument2 });
            }
            else
            {
                method(argument1, argument2);
            }
        }

        public void Invoke<T1, T2, T3>(Action<T1, T2, T3> method, T1 argument1, T2 argument2, T3 argument3)
        {
            if (InvokeRequired)
            {
                invokeTarget.BeginInvoke(method, new object[] { argument1, argument2, argument3 });
            }
            else
            {
                method(argument1, argument2, argument3);
            }
        }

        public void Invoke<T1, T2, T3, T4>(Action<T1, T2, T3, T4> method, T1 argument1, T2 argument2, T3 argument3, T4 argument4)
        {
            if (InvokeRequired)
            {
                invokeTarget.BeginInvoke(method, new object[] { argument1, argument2, argument3, argument4 });
            }
            else
            {
                method(argument1, argument2, argument3, argument4);
            }
        }

        public void Invoke<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> method, T1 argument1, T2 argument2, T3 argument3, T4 argument4, T5 argument5)
        {
            if (InvokeRequired)
            {
                invokeTarget.BeginInvoke(method, new object[] { argument1, argument2, argument3, argument4, argument5 });
            }
            else
            {
                method(argument1, argument2, argument3, argument4, argument5);
            }
        }

        public void Invoke<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> method, T1 argument1, T2 argument2, T3 argument3, T4 argument4, T5 argument5, T6 argument6)
        {
            if (InvokeRequired)
            {
                invokeTarget.BeginInvoke(method, new object[] { argument1, argument2, argument3, argument4, argument5, argument6 });
            }
            else
            {
                method(argument1, argument2, argument3, argument4, argument5, argument6);
            }
        }

        public void Invoke<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> method, T1 argument1, T2 argument2, T3 argument3, T4 argument4, T5 argument5, T6 argument6, T7 argument7)
        {
            if (InvokeRequired)
            {
                invokeTarget.BeginInvoke(method, new object[] { argument1, argument2, argument3, argument4, argument5, argument6, argument7 });
            }
            else
            {
                method(argument1, argument2, argument3, argument4, argument5, argument6, argument7);
            }
        }

        private bool InvokeRequired
        {
            get
            {
                return invokeTarget.InvokeRequired;
            }
        }
    }




}
